package com.tywj.panda.travel.details

import android.annotation.SuppressLint
import android.app.Activity
import android.content.Intent
import android.graphics.BitmapFactory
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.widget.TextView
import com.alibaba.android.arouter.facade.annotation.Route
import com.amap.api.maps.AMap
import com.amap.api.maps.model.*
import com.amap.api.navi.AmapNaviPage
import com.amap.api.navi.AmapNaviParams
import com.amap.api.navi.AmapNaviType
import com.amap.api.navi.AmapPageType
import com.amap.api.services.core.AMapException
import com.amap.api.services.core.LatLonPoint
import com.amap.api.services.route.*
import com.huawei.hms.hmsscankit.ScanUtil
import com.huawei.hms.ml.scan.HmsScan
import com.huawei.hms.ml.scan.HmsScanAnalyzerOptions
import com.tywj.lib.core.common.extension.*
import com.tywj.lib.core.common.util.BarUtil
import com.tywj.lib.core.common.util.LogUtil
import com.tywj.lib.core.common.util.ResourcesUtil
import com.tywj.lib.lifecycle.extension.attachToLifecycle
import com.tywj.lib.location.entity.LocationEntity
import com.tywj.lib.route.RouteParam
import com.tywj.lib.route.RouteUtil
import com.tywj.navigation.base.BaseMapActivity
import com.tywj.navigation.entity.DrivingRouteOverlay
import com.tywj.navigation.entity.GPSEntity
import com.tywj.navigation.popupwindow.MapDetailsPopUpImgView
import com.tywj.navigation.popupwindow.NavigationPopupWindow
import com.tywj.navigation.tool.MapTool
import com.tywj.panda.customer.common.constant.TravelStatusConstant
import com.tywj.panda.customer.common.entity.HomeLineDetailsEntity
import com.tywj.panda.customer.common.entity.TravelEntity
import com.tywj.panda.customer.common.http.PDArrayCallback
import com.tywj.panda.customer.common.http.PDObjectCallback
import com.tywj.panda.customer.common.http.PDStringCallback
import com.tywj.panda.customer.common.provider.IHomeService
import com.tywj.panda.customer.common.tool.PermissionTool
import com.tywj.panda.customer.common.tool.RotateUtils
import com.tywj.panda.customer.common.tool.TimeTool
import com.tywj.panda.travel.R
import com.tywj.panda.travel.api.TravelApi
import com.tywj.panda.travel.event.TravelEvent
import com.tywj.panda.travel.route.TravelRoute
import io.reactivex.Observable
import io.reactivex.disposables.Disposable
import kotlinx.android.synthetic.main.travel_activity_details.*
import java.util.concurrent.TimeUnit

/**
 * @desc 行程详情界面
 * @author June Yang
 * @date 2020/5/30
 */

@Route(path = TravelRoute.TRAVEL_DETAILS)
class TravelDetailsActivity : BaseMapActivity() {

    companion object {
        const val PARAMS_TRAVEL_ENTITY = "travelEntity"

        //是否从列表中过来，否则需要加载行程信息
        const val PRAMS__IS_FROM_LIST = "isFromList"

        //二维码返回数据
        const val REQUEST_CODE_SCAN_ONE = 0X01
    }

    private var id = ""

    //当关票的状态
    private var status = 0


    //是否显示
    private var isShowDetails = true

    private var bean = TravelEntity.DataBean()

    private val dialog by lazy { initRefundDialog() }

    private val dialogStatus by lazy { initRefundStatusDialog() }

    private val dialogTicket by lazy { initTicketDialog() }

    private var routeSearch: RouteSearch? = null

    //站点
    private var stations = ArrayList<HomeLineDetailsEntity.Station>()

    //最终选择的出发起始站点
    private var upStations = ArrayList<HomeLineDetailsEntity.Station>(2)

    //途径点坐标
    private var listRoute = ArrayList<ArrayList<Double>>()

    private var clickMarker: Marker? = null

    // 是否是第一次获取定位
    private var isFirstLocation = false

    //当前位置
    private var currentLocation: LocationEntity? = null

    //记录标记点
    private var listMaker = ArrayList<Marker>()

    private var lineCode = ""

    //定时刷新车辆GPS轨迹
    private var intervalRefreshDisposable: Disposable? = null

    override fun getLayoutID(): Int = R.layout.travel_activity_details

    override fun initVariable(savedInstanceState: Bundle?) {
        super.initVariable(savedInstanceState)

        bean = RouteParam(this).getParcelable(PARAMS_TRAVEL_ENTITY)!!

        loadData(bean)
    }

    override fun initView(savedInstanceState: Bundle?) {
        super.initView(savedInstanceState)

        BarUtil.setStatusBarColor(this, ResourcesUtil.getColor(R.color.common_white))
        BarUtil.setStatusBarLightMode(this.window, true)
    }

    override fun loadDataOnCreate() {
        super.loadDataOnCreate()

        RouteUtil.getServiceProvider(IHomeService::class.java)?.getCRMLineDetails(bean.lineCode)
            ?.attachToLifecycle(this)
            ?.execute(object : PDObjectCallback<HomeLineDetailsEntity>(HomeLineDetailsEntity::class.java) {
                override fun success(data: HomeLineDetailsEntity) {
                    handleData(data)
                }

                override fun error(code: Int, message: String) {
                    super.error(code, message)
                    shortToast(message)
                }
            })
    }


    override fun initListener() {
        super.initListener()

        ivArrowUp.onClick {
            isShowDetails = !isShowDetails
            RotateUtils.rotateArrow(ivArrowUp, isShowDetails)
            if (isShowDetails) {
                visible(llDetails)
                gone(tvPlateNo2)
            } else {
                gone(llDetails)
                visible(tvPlateNo2)
            }
        }

        tvRefund.onClick {
            dialog.showRefundDialog(supportFragmentManager, bean)
        }

        btnTicketTransfer.onClick {
            TravelRoute.toTicketTransfer(id).navigation(this)
        }
        btnSweepCheck.onClick {
            PermissionTool.camera {
                scanTickets()
            }
        }

        dialogTicket.setListenerConfirm {
            TravelEvent.loadTravelDataSuccessEvent.post(Unit)
            finish()
        }
        dialog.setConfirmOnClick { number, entity ->

            if (number > bean.number) {
                shortToast("不能超过最大购票数")
                return@setConfirmOnClick
            } else {
                refundTicket(number, entity)
            }
        }

        dialogStatus.setOnISeeListener {
            TravelEvent.loadTravelDataSuccessEvent.post(Unit)
            finish()
        }

        map.setInfoWindowAdapter(object : AMap.InfoWindowAdapter {
            var infoWindow: View? = null

            override fun getInfoContents(marker: Marker?): View {
                return View(this@TravelDetailsActivity)
            }

            override fun getInfoWindow(marker: Marker): View {
                if (infoWindow == null) {
                    infoWindow = LayoutInflater.from(this@TravelDetailsActivity)
                        .inflate(R.layout.navigation_map_infiwindow_layout, null)
                }

                infoWindow?.let {
                    render(marker, it)
                }
                return infoWindow!!
            }
        })

        map.setOnMarkerClickListener(AMap.OnMarkerClickListener { marker ->
            if (marker.title != null && marker.title != "") {
                clickMarker = marker
                clickMarker?.showInfoWindow()
            }
            true
        })

        map.setOnMapClickListener {
            if (clickMarker != null && clickMarker!!.isInfoWindowShown) {
                clickMarker!!.hideInfoWindow()
                clickMarker = null
            }
        }
    }

    override fun onResume() {
        super.onResume()

        //开始轮询车辆轨迹GPS
        intervalRefreshDisposable = refreshBusGPSRoute()
    }

    override fun onStop() {
        super.onStop()

        intervalRefreshDisposable?.safeDisposable()
    }

    override fun onMyLocationChange(location: LocationEntity) {
        super.onMyLocationChange(location)

        if (!isFirstLocation) {
            // 第一次获取定位数据，将地址显示到该位置
            isFirstLocation = true
            currentLocation = location
            currentLocation?.let {
                toLocation(it.latitude, it.longitude, MapTool.ZOOM_LEVEL_DEFAULT)
            }
        }
    }

    @SuppressLint("SetTextI18n")
    private fun loadData(bean: TravelEntity.DataBean) {
        tvLineBusName.text = bean.lineName
        tvTime.text = bean.lineDate + " " + bean.lineTime

        tvMayStartTime.text = bean.onTime
        tvMayEndTime.text = bean.offTime

        tvStartPoint.text = bean.startStation
        tvEndPoint.text = bean.endStation

        val platNo = "车牌号:" + if (bean.vehicleNo.isEmpty()) {
            "调度中"
        } else {
            bean.vehicleNo
        }
        tvTicketNumber.text = "车票数:" + bean.number + "张"
        tvPlateNo.text = platNo
        tvPlateNo2.text = platNo

        status = bean.status
        lineCode = bean.lineCode

        when (status) {

            //未出票
            TravelStatusConstant.STATUS_NO_TICKET -> {
                gone(ivStatus, tvRefund, tvTips, flTransferOrSweepCheck)
            }

            //待派车 （正常状态）
            TravelStatusConstant.STATUS_WAIT_CAR -> {
                gone(ivStatus, flTransferOrSweepCheck)
                visible(tvRefund, tvTips)
            }

            //已派车 （正常状态）才能扫码
            TravelStatusConstant.STATUS_HAD_CAR -> {
                gone(ivStatus)
                visible(tvRefund, tvTips, flTransferOrSweepCheck)
            }
            //已验票
            TravelStatusConstant.STATUS_TYPE_HAD_RECOUNT -> {
                //隐藏退款、 调度提示、和转让和扫码
                gone(tvRefund, tvTips, flTransferOrSweepCheck)
                visible(ivStatus)

                ivStatus.setBackgroundResource(R.drawable.travel_had_recount)

            }

            //退票已受理 +已退票
            TravelStatusConstant.STATUS_TYPE_REFUND_ACCEPTED, TravelStatusConstant.STATUS_TYPE_HAD_REFUND -> {
                //隐藏退款、 调度提示、和转让和扫码
                gone(tvRefund, tvTips, flTransferOrSweepCheck)
                visible(ivStatus)
                ivStatus.setBackgroundResource(R.drawable.travel_had_refund)
            }

            //已过期
            TravelStatusConstant.STATUS_TYPE_HAD_EXPIRED -> {
                //隐藏退款、 调度提示、和转让和扫码
                gone(tvRefund, tvTips, flTransferOrSweepCheck)
                visible(ivStatus)
                ivStatus.setBackgroundResource(R.drawable.travel_had_expired)
            }

            //已过期
            else -> {
                //隐藏退款、 调度提示、和转让和扫码
                gone(tvRefund, tvTips, flTransferOrSweepCheck)
                visible(ivStatus)
                ivStatus.setBackgroundResource(R.drawable.travel_had_expired)
            }
        }
    }

    private fun initRefundDialog(): TravelRefundDialog {
        return supportFragmentManager.findFragmentByTag(TravelRefundDialog.TAG) as? TravelRefundDialog
            ?: TravelRefundDialog()
    }

    private fun initRefundStatusDialog(): TravelRefundStatusDialog {
        return supportFragmentManager.findFragmentByTag(TravelRefundStatusDialog.TAG) as? TravelRefundStatusDialog
            ?: TravelRefundStatusDialog()
    }

    private fun initTicketDialog(): TravelTicketDialog {
        return supportFragmentManager.findFragmentByTag(TravelTicketDialog.TAG) as? TravelTicketDialog
            ?: TravelTicketDialog()
    }

    //扫码验票
    private fun scanTickets() {
        ScanUtil.startScan(
            this,
            REQUEST_CODE_SCAN_ONE, HmsScanAnalyzerOptions.Creator().create()
        )
    }

    //Activity回调
    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (resultCode != Activity.RESULT_OK || data == null) {
            return
        }
        if (requestCode == REQUEST_CODE_SCAN_ONE) {
            val hmResult: HmsScan = data.getParcelableExtra(ScanUtil.RESULT)

            hmResult.let {
                val deviceCode = it.originalValue
                checkTickets(deviceCode)
            }
        }
    }

    /**
     * 用户端扫码验票
     */
    private fun checkTickets(deviceCode: String) {
        showLoadingDialog()
        TravelApi.checkTickets(
            driverCode = deviceCode,
            number = bean.number,
            ticketCode = bean.ticketCode,
            goodsNo = bean.goodsNo
        )
            .attachToLifecycle(this).execute(object : PDStringCallback() {
                override fun success(message: String) {
                    dialogTicket.showTicketDialog(supportFragmentManager, bean.vehicleNo, bean.number)
                }

                override fun error(code: Int, message: String) {
                    super.error(code, message)
                    shortToast(message)
                }

                override fun onComplete() {
                    super.onComplete()
                    dismissLoadingDialog()
                }
            })
    }

    /**
     * 退票
     */
    private fun refundTicket(number: Int, entity: TravelEntity.DataBean?) {
        showLoadingDialog()
        TravelApi.refundTickets(
            number = number,
            ticketNo = entity!!.ticketCode,
            svrFee = entity.chargeService,
            refundFee = entity.refundFee
        )
            .attachToLifecycle(this).execute(object : PDStringCallback() {
                override fun success(message: String) {

                    dialogStatus.showRefundStatusDialog(
                        supportFragmentManager,
                        titleTips = ResourcesUtil.getString(R.string.travel_refund_success_title),
                        des = ResourcesUtil.getString(R.string.travel_refund_success_tips)
                    )
                }

                override fun error(code: Int, message: String) {
                    super.error(code, message)

                    dialogStatus.showRefundStatusDialog(
                        supportFragmentManager,
                        titleTips = ResourcesUtil.getString(R.string.travel_refund_fail_title),
                        des = ResourcesUtil.getString(R.string.travel_refund_fail_tips),
                        isFail = true
                    )
                }

                override fun onComplete() {
                    super.onComplete()
                    dismissLoadingDialog()
                }
            })
    }

    private fun handleData(data: HomeLineDetailsEntity) {

        stations.clear()
        //拼接站点信息
        stations.add(data.start)
        stations.addAll(data.ways)
        stations.add(data.end)

        listRoute = data.route

        upStations.add(stations.first())
        upStations.add(stations.last())

        refreshBusTimeList()
        startRouteSearch()

    }

    /**
     * 开始路径规划
     * 驾车出行路线规划
     * https://lbs.amap.com/api/android-sdk/guide/route-plan/drive/#t6
     */

    private fun startRouteSearch() {
        //第一步
        routeSearch = RouteSearch(this)

        /**
         * 第二步
         * 设置数据回调监听器
         * 驾车出行路线规划
         * 高德接口链接：https://lbs.amap.com/api/android-sdk/guide/route-plan/drive
         */
        routeSearch?.setRouteSearchListener(object : RouteSearch.OnRouteSearchListener {
            override fun onBusRouteSearched(busRouteResult: BusRouteResult, i: Int) {

            }

            /**
             * 第五步 接受数据
             *
             *
             */
            override fun onDriveRouteSearched(driveRouteResult: DriveRouteResult, rCode: Int) {

                if (rCode == AMapException.CODE_AMAP_SUCCESS) {
                    if (driveRouteResult.paths != null) {
                        val drivePath = driveRouteResult.paths[0] ?: return
                        val drivingRouteOverlay = DrivingRouteOverlay(
                            this@TravelDetailsActivity, map, drivePath,
                            driveRouteResult.startPos,
                            driveRouteResult.targetPos, null, stations.first(), stations.last()
                        )
                        drivingRouteOverlay.setNodeIconVisibility(false) //设置节点marker是否显示
                        drivingRouteOverlay.setIsColorfulline(true) //是否用颜色展示交通拥堵情况，默认true
                        drivingRouteOverlay.removeFromMap()
                        drivingRouteOverlay.addToMap()
                        drivingRouteOverlay.zoomToSpan()
                    }
                } else {
                    shortToast("路径获取失败")
                }

            }

            override fun onWalkRouteSearched(walkRouteResult: WalkRouteResult, i: Int) {}
            override fun onRideRouteSearched(rideRouteResult: RideRouteResult, i: Int) {}
        })


        val start = LatLonPoint(upStations[0].loc.last(), upStations[0].loc.first())
        val end = LatLonPoint(upStations[1].loc.last(), upStations[1].loc.first())

        val fromAndTo = RouteSearch.FromAndTo(start, end)

        val latLonPoints: MutableList<LatLonPoint> = ArrayList()

        val markerOption = MarkerOptions()
        markerOption.draggable(false) //设置Marker可拖动

        markerOption.icon(
            BitmapDescriptorFactory.fromBitmap(
                BitmapFactory.decodeResource(resources, R.drawable.jing)
            )
        )
        // 将Marker设置为贴地显示，可以双指下拉地图查看效果
        markerOption.isFlat = true //设置marker平贴地图效果

        for (i in 1 until stations.size - 1) {
            val latLng = LatLng(stations[i].loc[1], stations[i].loc[0])
            markerOption.title(stations[i].name)
            markerOption.snippet("预计到达：" + stations[i].timeAdd + "？" + stations[i].img + "？" + stations[i].info)
            map.addMarker(markerOption.position(latLng))
        }

        //listRoute 二维数组遍历 途径点数据
        listRoute.forEach {
            //注意经纬度的顺序 移动端SDK经纬度的格式为‘纬度,经度’。
            val point = LatLonPoint(it.last(), it.first())
            latLonPoints.add(point)
        }

        /**
         * 第三步
         *设置搜索参数
         * fromAndTo包含路径规划的起点和终点，
         * drivingMode表示驾车模式  //返回的结果会优先考虑高速路，并且会考虑路况躲避拥堵，与高德地图的“躲避拥堵&高速优先”策略一致
         * 第三个参数表示途经点（最多支持16个），第四个参数表示避让区域（最多支持32个），第五个参数表示避让道路
         */
        val query = RouteSearch.DriveRouteQuery(
            fromAndTo,
            RouteSearch.DRIVING_SINGLE_DEFAULT,
            latLonPoints,
            null,
            ""
        )
        /**
         * 第四步：发送请求
         */
        routeSearch?.calculateDriveRouteAsyn(query)
    }

    private fun render(marker: Marker, view: View) {
        val time = view.findViewById<TextView>(R.id.time)
        val name = view.findViewById<TextView>(R.id.name)
        val photo = view.findViewById<TextView>(R.id.tvSeeReal)
        val daohang = view.findViewById<TextView>(R.id.tvNavigation)
        val infos = marker.snippet.split("？").toTypedArray()
        time.text = infos[0]
        name.text = marker.title

        photo.setOnClickListener {
            if (marker.title != null && marker.title != "") {

                val path = marker.snippet.split("？").toTypedArray()[1]
                val info = marker.snippet.split("？").toTypedArray()[2]

                LogUtil.d("图片地址:$path")
                if (path.isNotEmpty()) {
                    val mpopUpWindows =
                        MapDetailsPopUpImgView(this, path, info)
                    mpopUpWindows.show()
                } else {
                    shortToast("暂无站点图片")
                }
            }
        }
        val popupWindow = NavigationPopupWindow(this, marker.position)

        popupWindow.goHereListener {
            currentLocation?.let {
                toStartNavigation(it, marker.position)
            }

        }
        daohang.setOnClickListener { v ->
            popupWindow.showAtDropDownCenter(v)

        }
    }


    //根据用户选择的班次时刻表 同步显示每站的时间表(stations中处理站点信息的时间点 站点之间需要累加实现总时间)
    private fun refreshBusTimeList() {

        var totalTime = 0

        stations.forEachIndexed { index, station ->
            for (i in 0..index) {
                if (i == index) {
                    totalTime += station.time
//                    LogUtil.d("当前第$index" + "值为" + station.time + ",当前时间总和 :$totalTime")
                    break
                }
            }
            //发车时间计算
            station.timeAdd = TimeTool.formatTimeAdd(bean.lineTime, totalTime.toString())
        }
    }

    private fun toStartNavigation(start: LocationEntity, end: LatLng) {
        val mStart = Poi("我的位置", LatLng(start.latitude, start.longitude), "")
        val mEnd = Poi("终点位置", LatLng(end.latitude, end.longitude), "")

        AmapNaviPage.getInstance().showRouteActivity(
            this,
            AmapNaviParams(mStart, null, mEnd, AmapNaviType.DRIVER, AmapPageType.NAVI),
            null
        )
    }

    //轮询获取车辆经纬度
    private fun getGpsRoute(lineCode: String) {

        RouteUtil.getServiceProvider(IHomeService::class.java)?.getGpsRoute(lineCode)
            ?.attachToLifecycle(this)
            ?.execute(object : PDArrayCallback<GPSEntity>(GPSEntity::class.java) {
                override fun success(data: ArrayList<GPSEntity>) {
                    handGPSData(data)
                    LogUtil.d("get gps route success")
                }

                override fun error(code: Int, message: String) {
                    super.error(code, message)
                    LogUtil.d("get gps route fail:$message")
                }
            })
    }

    private fun handGPSData(list: ArrayList<GPSEntity>) {
        if (list.isEmpty()) return
        val gpsList = ArrayList<ArrayList<Double>>()

        list.forEach {
            gpsList.add(it.loc)
        }
        //组成一个二维数组
        markerBusPoint(gpsList)
    }

    private fun refreshBusGPSRoute(): Disposable? {
        val disposable = Observable.interval(0, 10, TimeUnit.SECONDS).applyScheduler(
        ).subscribe({

            if (lineCode.isNotEmpty()) {
                getGpsRoute(lineCode)
            }

        }, {
            LogUtil.printStackTrace(it)
        })
        disposable.attachToLifecycle(this)
        return disposable
    }

    private fun markerBusPoint(list: ArrayList<ArrayList<Double>>) {
        if (list.isEmpty()) return
        //标记前 先清除标记再绘制新的标记点
        listMaker.forEach {
            if (it.title == "car") {
                it.remove()
            }
        }
        list.forEach {
            val markerOption = MarkerOptions()
            val latLng = LatLng(it.last(), it.first())
            //设置Marker覆盖物的位置坐标。
            markerOption.position(latLng)
            //设置 Marker覆盖物 的标题 区分经过点的标记
            markerOption.title("car")
            markerOption.icon(
                BitmapDescriptorFactory.fromBitmap(
                    BitmapFactory.decodeResource(
                        ResourcesUtil.resources,
                        R.drawable.navigation_icon_marker_bus
                    )
                )
            )
            val marker = map.addMarker(markerOption.position(latLng))
            listMaker.add(marker)
        }
    }
}